﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Sinacor.Infra.Service.Validation;
using Sinacor.Infra.Service.Common;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using Sinacor.Infra.Service.Validation.BusinessRules;
using Sinacor.Infra.Common.Validation;
using Sinacor.Servico.Bovespa.Alocacao.BusinessLogic;

namespace Sinacor.Servico.Bovespa.Alocacao.BusinessLogic.BusinessRuleValidation
{
    public class ValidadorOrdemDistribuidaVendaDescoberta : BaseBusinessRuleValidation<BusinessEntity.VendaDescoberta>, IBusinessRuleValidation
    {
        private int _erroExistemOrdensDistribuidas = 109593;
        private int _erroAoGerarCodigoCasamento = 109592;
        private int _erroQdteInformadaMaior = 109891;
        private int _erroObjetoNulo = 314816;

        public int ErroExistemOrdensDistribuidas
        {
            get { return _erroExistemOrdensDistribuidas; }
            set { _erroExistemOrdensDistribuidas = value; }
        }

        public int ErroAoGerarCodigoCasamento
        {
            get { return _erroAoGerarCodigoCasamento; }
            set { _erroAoGerarCodigoCasamento = value; }
        }

        public int ErroQdteInformadaMaior
        {
            get { return _erroQdteInformadaMaior; }
            set { _erroQdteInformadaMaior = value; }
        }

        public int ErroObjetoNulo
        {
            get { return _erroObjetoNulo; }
            set { _erroObjetoNulo = value; }
        }

		#region Métodos 
		public List<Infra.Common.Validation.ValidationError> GetErrors()
        {
            return base.ErrorsList;
		}

		public void Validate()
        {
            if (base.EntityToValidate != null)
            {
                if (!ValidarQuantidade(EntityToValidate))
                {
                    base.AddValidationError(ErroQdteInformadaMaior);
                    return;
                }

                BusinessEntity.Parameter.FiltroVerificaOrdemDistribuida filtro = new Sinacor.Servico.Bovespa.Alocacao.BusinessEntity.Parameter.FiltroVerificaOrdemDistribuida();
                filtro.CodigoCliente = EntityToValidate.Cliente;
                filtro.DataPregao = EntityToValidate.DataPregao;

                Parametro.BusinessEntity.Parametro parametroBE = new Sinacor.Servico.Bovespa.Parametro.BusinessEntity.Parametro();
                Parametro.BusinessLogic.Parametro parametro = new Sinacor.Servico.Bovespa.Parametro.BusinessLogic.Parametro();
                parametroBE = parametro.ObterParametro();

                if (parametroBE.JuntaFracionario.ToString() == "S")
                {
                    Bovespa.Titulo.BusinessEntity.Titulo tituloBE = new Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Titulo();
                    Bovespa.Titulo.BusinessEntity.Titulo tituloBERetornado = new Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Titulo();
                    Bovespa.Titulo.BusinessLogic.Titulo titulo = new Sinacor.Servico.Bovespa.Titulo.BusinessLogic.Titulo();
                    tituloBE.Codigo = EntityToValidate.Ativo;
                    tituloBE.DataOrdem = EntityToValidate.DataPregao;

                    tituloBERetornado = titulo.ObterTitulo(tituloBE);

                    if ((tituloBERetornado.TipoMercado.Value == Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Enum.TipoMercado.Vista) || (tituloBERetornado.TipoMercado.Value == Sinacor.Servico.Bovespa.Titulo.BusinessEntity.Enum.TipoMercado.Fracionario))
                    {
                        ManutencaoOrdens.BusinessEntity.Ordem maOrdem = new Sinacor.Servico.Bovespa.ManutencaoOrdens.BusinessEntity.Ordem();
                        ManutencaoOrdens.BusinessLogic.ManutencaoOrdens maOrdensBL = new Sinacor.Servico.Bovespa.ManutencaoOrdens.BusinessLogic.ManutencaoOrdens();
                        Bovespa.ManutencaoOrdens.BusinessEntity.Resultado resultado = new Sinacor.Servico.Bovespa.ManutencaoOrdens.BusinessEntity.Resultado();

                        maOrdem.Ativo = EntityToValidate.Ativo;
                        maOrdem.CodigoISIN = tituloBERetornado.CodigoISIN;
                        maOrdem.Mercado = (Bovespa.ManutencaoOrdens.BusinessEntity.Enum.TipoMercado?)tituloBERetornado.TipoMercado;

                        resultado = maOrdensBL.GerarCodigoCasamento(maOrdem);

                        if (resultado.Sucesso == false)
                        {
                            if (resultado.CodigoErro == -1)
                            {
                                base.AddValidationError(ErroAoGerarCodigoCasamento);
                                return;
                            }
                            else
                            {
                                Bovespa.Alocacao.BusinessLogic.AlocacaoCarteiraVendaDescoberta alocacaoCarteira = new AlocacaoCarteiraVendaDescoberta();
                                Bovespa.Alocacao.BusinessEntity.Resultado resultadoAlocacao = new Sinacor.Servico.Bovespa.Alocacao.BusinessEntity.Resultado();
                                resultadoAlocacao.Argumentos = resultado.Argumentos;
                                resultadoAlocacao.CodigoErro = resultado.CodigoErro;
                                resultadoAlocacao.Sucesso = resultado.Sucesso;
                                resultadoAlocacao.Valor = resultado.Valor; 
                                alocacaoCarteira.TratarExcecoes(resultadoAlocacao);
                            }

                        }
                        else
                        {
                            filtro.CodigoCasamento = Convert.ToString(resultado.Valor);

                            ResourceAccess.AlocacaoCarteiraVendaDescoberta raAlocacao = new Sinacor.Servico.Bovespa.Alocacao.ResourceAccess.AlocacaoCarteiraVendaDescoberta();
                            if (raAlocacao.VerificarOrdemDistribuida(filtro))
                            {
                                base.AddValidationError(ErroExistemOrdensDistribuidas, null,
                                    new List<object> 
                                    { 
                                        this.EntityToValidate.Cliente.ToString(),
                                        this.EntityToValidate.Ativo,
                                        "Venda",
                                        this.EntityToValidate.DataPregao.ToShortDateString() 
                                    });
                                return;
                            }
                        }

                    }
                    else
                    {
                        filtro.Ativo = EntityToValidate.Ativo;

                        ResourceAccess.AlocacaoCarteiraVendaDescoberta raAlocacao = new Sinacor.Servico.Bovespa.Alocacao.ResourceAccess.AlocacaoCarteiraVendaDescoberta();
                        if (raAlocacao.VerificarOrdemDistribuida(filtro))
                        {
                            base.AddValidationError(ErroExistemOrdensDistribuidas, null,
                                new List<object> 
                                { 
                                    this.EntityToValidate.Cliente.ToString(),
                                    this.EntityToValidate.Ativo,
                                    "Venda",
                                    this.EntityToValidate.DataPregao.ToShortDateString() 
                                });
                            return;
                        }
                        
                    }
                }
                else
                {
                    filtro.Ativo = EntityToValidate.Ativo;
                    
                    ResourceAccess.AlocacaoCarteiraVendaDescoberta raAlocacao = new Sinacor.Servico.Bovespa.Alocacao.ResourceAccess.AlocacaoCarteiraVendaDescoberta();
                    raAlocacao.VerificarOrdemDistribuida(filtro);

                    if (raAlocacao.VerificarOrdemDistribuida(filtro))
                    {
                        base.AddValidationError(ErroExistemOrdensDistribuidas, null,
                            new List<object> 
                            { 
                                this.EntityToValidate.Cliente.ToString(),
                                this.EntityToValidate.Ativo,
                                "Venda",
                                this.EntityToValidate.DataPregao.ToShortDateString() 
                            });
                        return;
                    }
                }
            }
            else
                base.AddValidationError(ErroObjetoNulo);

		} 

        private bool ValidarQuantidade(BusinessEntity.VendaDescoberta entity)
        {
            // Se a alocacao da carteira for informada
            // E for maior que a quantidade disponivel da carteira
            // OU maior que a quantidade descoberta total
            // retornar falso
            if (entity.AlocacaoCarteira219 != null && (
                entity.AlocacaoCarteira219 > entity.PosicaoCarteira219 ||
                entity.AlocacaoCarteira219 > entity.QuantidadeDescoberta))
                return false;

            if (entity.AlocacaoCarteira239 != null && (
                entity.AlocacaoCarteira239 > entity.PosicaoCarteira239 ||
                entity.AlocacaoCarteira239 > entity.QuantidadeDescoberta))
                return false;

            if (entity.AlocacaoCarteira280 != null && (
                entity.AlocacaoCarteira280 > entity.PosicaoCarteira280 ||
                entity.AlocacaoCarteira280 > entity.QuantidadeDescoberta))
                return false;

            if (entity.AlocacaoCarteira274 != null && (
                entity.AlocacaoCarteira274 > entity.PosicaoCarteira274 ||
                entity.AlocacaoCarteira274 > entity.QuantidadeDescoberta))
                return false;

            return true;
        }

		#endregion Métodos 
    }
}
